package com.qiaoba.nosql.redis.service;

import org.springframework.data.redis.core.ZSetOperations;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Redis 服务层, 提供常见的Redis操作方法
 *
 * @author ailanyin
 * @date 2023-09-09 18:46:07
 */
public interface RedisService {

    /**
     * 保存属性
     *
     * @param key   属性的键
     * @param value 属性的值
     * @param time  过期时间（秒）
     */
    void set(String key, Object value, long time);

    /**
     * 保存属性
     *
     * @param key   属性的键
     * @param value 属性的值
     */
    void set(String key, Object value);

    /**
     * 获取属性
     *
     * @param key 属性的键
     * @return 属性的值
     */
    Object get(String key);

    /**
     * 删除属性
     *
     * @param key 属性的键
     * @return 如果删除成功，返回true；否则返回false
     */
    Boolean del(String key);

    /**
     * 批量删除属性
     *
     * @param keys 属性的键列表
     * @return 删除的属性数量
     */
    Long del(List<String> keys);

    /**
     * 设置过期时间
     *
     * @param key  属性的键
     * @param time 过期时间（秒）
     * @return 如果设置成功，返回true；否则返回false
     */
    Boolean expire(String key, long time);

    /**
     * 获取过期时间
     *
     * @param key 属性的键
     * @return 过期时间（秒）
     */
    Long getExpire(String key);

    /**
     * 判断是否有该属性
     *
     * @param key 属性的键
     * @return 如果属性存在，返回true；否则返回false
     */
    Boolean hasKey(String key);

    /**
     * 按delta递增
     *
     * @param key   属性的键
     * @param delta 递增的步长
     * @return 递增后的属性值
     */
    Long incr(String key, long delta);

    /**
     * 按delta递减
     *
     * @param key   属性的键
     * @param delta 递减的步长
     * @return 递减后的属性值
     */
    Long decr(String key, long delta);

    /**
     * 获取Hash结构中的属性
     *
     * @param key     Hash结构的键
     * @param hashKey 属性的键
     * @return 属性的值
     */
    Object hGet(String key, String hashKey);

    /**
     * 向Hash结构中放入一个属性
     *
     * @param key     Hash结构的键
     * @param hashKey 属性的键
     * @param value   属性的值
     * @param time    过期时间（秒）
     * @return 如果设置成功，返回true；否则返回false
     */
    Boolean hSet(String key, String hashKey, Object value, long time);

    /**
     * 向Hash结构中放入一个属性
     *
     * @param key     Hash结构的键
     * @param hashKey 属性的键
     * @param value   属性的值
     */
    void hSet(String key, String hashKey, Object value);

    /**
     * 向ZSet结构中放入一个属性
     *
     * @param key   键
     * @param value 值
     * @param score 分数
     */
    void addSortSet(String key, Object value, long score);

    /**
     * 删除ZSet结构中的一个属性
     *
     * @param key   key
     * @param value value
     */
    void delSortSet(String key, String value);

    /**
     * 获取ZSet中值的分数
     *
     * @param key   键
     * @param value 值
     * @return 分数
     */
    Double getSortSetScore(String key, Object value);

    /**
     * 获取ZSet大小
     *
     * @param key 键
     * @return 大小
     */
    Long sortSetSize(String key);

    /**
     * 分页获取ZSet结构中的数据
     *
     * @param key      key
     * @param pageNum  当前页码
     * @param pageSize 每页条数
     * @param isAsc    分数正序排序
     * @return list
     */
    Set<Object> zSetPage(String key, Integer pageNum, Integer pageSize, boolean isAsc);

    /**
     * ZSet总数
     *
     * @param key key
     * @return total
     */
    Long zSetTotal(String key);

    /**
     * 分页获取ZSet结构中的数据和分数
     *
     * @param key      key
     * @param pageNum  当前页码
     * @param pageSize 每页条数
     * @param isAsc    分数正序排序
     * @return list
     */
    Set<ZSetOperations.TypedTuple<Object>> zSetScorePage(String key, Integer pageNum, Integer pageSize, boolean isAsc);

    /**
     * 获取所有ZSet结构中的数据和分数
     *
     * @param key   key
     * @param isAsc 分数正序排序
     * @return list
     */
    Set<ZSetOperations.TypedTuple<Object>> zSetScoreAll(String key, boolean isAsc);

    /**
     * 模糊查询所有key
     *
     * @param key key
     * @return keys
     */
    Collection<String> getKeys(String key);

    /**
     * 直接获取整个Hash结构
     *
     * @param key Hash结构的键
     * @return 整个Hash结构
     */
    Map<Object, Object> hGetAll(String key);

    /**
     * 直接设置整个Hash结构
     *
     * @param key  Hash结构的键
     * @param map  属性的键值对
     * @param time 过期时间（秒）
     * @return 如果设置成功，返回true；否则返回false
     */
    Boolean hSetAll(String key, Map<String, Object> map, long time);

    /**
     * 直接设置整个Hash结构
     *
     * @param key Hash结构的键
     * @param map 属性的键值对
     */
    void hSetAll(String key, Map<String, ?> map);

    /**
     * 删除Hash结构中的属性
     *
     * @param key     Hash结构的键
     * @param hashKey 属性的键
     */
    void hDel(String key, Object... hashKey);

    /**
     * 判断Hash结构中是否有该属性
     *
     * @param key     Hash结构的键
     * @param hashKey 属性的键
     * @return 如果属性存在，返回true；否则返回false
     */
    Boolean hHasKey(String key, String hashKey);

    /**
     * Hash结构中属性递增
     *
     * @param key     Hash结构的键
     * @param hashKey 属性的键
     * @param delta   递增的步长
     * @return 递增后的属性值
     */
    Long hIncr(String key, String hashKey, Long delta);

    /**
     * Hash结构中属性递减
     *
     * @param key     Hash结构的键
     * @param hashKey 属性的键
     * @param delta   递减的步长
     * @return 递减后的属性值
     */
    Long hDecr(String key, String hashKey, Long delta);

    /**
     * 获取整个hash结构的大小
     *
     * @param key key
     * @return size
     */
    Long hSize(String key);

    /**
     * 获取Set结构
     *
     * @param key Set结构的键
     * @return Set结构中的元素
     */
    Set<Object> sMembers(String key);

    /**
     * 向Set结构中添加属性
     *
     * @param key    Set结构的键
     * @param values 要添加的元素
     * @return 添加的元素数量
     */
    Long sAdd(String key, Object... values);

    /**
     * 向Set结构中添加属性
     *
     * @param key    Set结构的键
     * @param time   过期时间（秒）
     * @param values 要添加的元素
     * @return 添加的元素数量
     */
    Long sAdd(String key, long time, Object... values);

    /**
     * 是否为Set中的属性
     *
     * @param key   Set结构的键
     * @param value 要检查的元素
     * @return 如果元素存在于Set中，返回true；否则返回false
     */
    Boolean sIsMember(String key, Object value);

    /**
     * 获取Set结构的长度
     *
     * @param key Set结构的键
     * @return Set结构的长度
     */
    Long sSize(String key);

    /**
     * 删除Set结构中的属性
     *
     * @param key    Set结构的键
     * @param values 要删除的元素
     * @return 删除的元素数量
     */
    Long sRemove(String key, Object... values);

    /**
     * 获取List结构中的属性
     *
     * @param key   List结构的键
     * @param start 起始索引
     * @param end   结束索引
     * @return List结构中指定范围的元素
     */
    List<Object> lRange(String key, long start, long end);

    /**
     * 分页获取List结构中的数据
     *
     * @param key      key
     * @param pageNum  当前页码
     * @param pageSize 每页条数
     * @return list
     */
    List<Object> lPage(String key, Integer pageNum, Integer pageSize);

    /**
     * 获取List结构的长度
     *
     * @param key List结构的键
     * @return List结构的长度
     */
    Long lSize(String key);

    /**
     * 根据索引获取List中的属性
     *
     * @param key   List结构的键
     * @param index 索引
     * @return 索引处的元素
     */
    Object lIndex(String key, long index);

    /**
     * 向List结构中添加属性
     *
     * @param key   List结构的键
     * @param value 要添加的元素
     * @return 添加后List结构的长度
     */
    Long lPush(String key, Object value);

    /**
     * 向List结构中添加属性
     *
     * @param key   List结构的键
     * @param value 要添加的元素
     * @param time  过期时间（秒）
     * @return 添加后List结构的长度
     */
    Long lPush(String key, Object value, long time);

    /**
     * 向List结构中批量添加属性
     *
     * @param key    List结构的键
     * @param values 要添加的元素列表
     * @return 添加后List结构的长度
     */
    Long lPushAll(String key, Object... values);

    /**
     * 向List结构中批量添加属性
     *
     * @param key    List结构的键
     * @param time   过期时间（秒）
     * @param values 要添加的元素列表
     * @return 添加后List结构的长度
     */
    Long lPushAll(String key, Long time, Object... values);

    /**
     * 从List结构中移除属性
     *
     * @param key   List结构的键
     * @param count 移除的元素数量
     * @param value 要移除的元素
     * @return 移除的元素数量
     */
    Long lRemove(String key, long count, Object value);

    /**
     * get object
     *
     * @param key   key
     * @param clazz clazz
     * @param <T>   T
     * @return clazz
     */
    <T> T getObject(String key, Class<T> clazz);


    /**
     * get list
     *
     * @param key   key
     * @param clazz clazz
     * @param <T>   T
     * @return // List<clazz>
     */
    <T> List<T> getObjectList(String key, Class<T> clazz);

    /**
     * hGetObject
     *
     * @param key     key
     * @param hashKey hashKey
     * @param clazz   clazz
     * @param <T>     T
     * @return clazz
     */
    <T> T hGetObject(String key, String hashKey, Class<T> clazz);

}
